iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
0

寫一個 Thread 接收 Socket


public class ServerListener extends Thread{

    @Override
    public void run() {

        try {
            @SuppressWarnings("resource")
            ServerSocket serverSocket = new ServerSocket(12345);
            while(true) {
            
                // accept() 會阻塞,等待用戶加入
                Socket socket = serverSocket.accept();
                
                // 創一個 ChatSocket 物件,用於讀取、寫入
                ChatSocket cs = new ChatSocket(socket);
                
                // ChatManager 的 SingleTon 管理這些 Socket
                ChatManager.getChatManager().add(cs);
                
                //run
                cs.start();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    };

	
}

serverSocket.accept() 阻塞等待 Socket 傳入

接著看一下 ChatSocket 物件


public class ChatSocket extends Thread{

	Socket socket ;
	
	public ChatSocket(Socket s) {
        this.socket = s;
        
        // 對自己推送訊息
		out("**已成功連線,歡迎加入聊天室**");
	}
	
	@Override
	public void run() {
		BufferedReader br;
		try {
			br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));
			String line = null;
			while(socket.isConnected()){
				line = br.readLine();
                // null 和 心跳包符號 不推送
                // 其餘都推
				if(line != null && !line.equals("$")) {
                    // 對陣列所有 Socket 用戶推送訊息
					ChatManager.getChatManager().publish(line);
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				socket = null;
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
	}
	
    // 推送
	public void out(String out) {
		out = out + "\n";
		try {
            // 寫的對象為自己的 Socket
			socket.getOutputStream().write(out.getBytes("UTF-8"));
		}  catch (IOException e) {
			e.printStackTrace();
		}
	}

}

ChatManager 管理所有的 ChatSocket

並對每個 ChatSocket 持有的 Socket 對象操作


public class ChatManager {

	ArrayList<String> arrayList = new ArrayList<>();
	private ChatManager() {}
	private static final ChatManager cm = new ChatManager();
	public static ChatManager getChatManager() {
		return cm;
	}
    
	// Vector 存所有 ChatSocket
	Vector<ChatSocket> vector = new Vector<ChatSocket>();
	
	public void add(ChatSocket cs) {
		vector.add(cs);
	}

	public void publish(String out) {
        
		for(int i = 0 ; i < vector.size() ; i++) {
            // 藉由每個 ChatSocket 取得 Socket 對象
            ChatSocket csChatSocket = vector.get(i);
			if(!csChatSocket.socket.isClosed() && csChatSocket.socket.isConnected()){
                // 對每個用戶 Socket 將訊息推送出去
				csChatSocket.out(out);
				
			}else  {
				vector.get(i).socket = null;
				vector.remove(i);
				i = i--;
			}
		}
	}
	
}



上一篇
Day23 - ServerSocket 聊天室 闡述做法
下一篇
Day25 - 聊天室 用戶端
系列文
菜雞 Android APP 從安裝 Android Studio 到上架 Google Play30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言